package com.jt.service;/**
 * @Author 金帮嘉诚 @Date 2021-08-03 星期二 10:54
 */
/*本类用于测试*/

/**知识点*/

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import com.jt.util.MyUtil;
import com.jt.vo.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.UUID;

/**
 * @author 刘昱江
 * 时间 2021/5/11
 */
@Service
//@Transactional  //当前类中的所有的方法都有事务控制 增/删/改需要事务  查询不要事务.
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    //*****************************************自己添加的部分******************************************************

    /**
     * 根据id更新user表中某条数据的密码
     * */
    @Override
    public Integer MyUpdateUserById(User user) {
        //设置密码转md5
        MyUtil.mySetMd5Password(user);
        //获取当前时间
//        java.sql.Timestamp now = MyUtil.myTimeNow();
//        user.setUpdated(now);
        return userMapper.updateById(user);
    }

    /**
     * 用户列表展现 我的实现
     * */
    @Override
    public PageResult getByPage(PageResult pageResult) {
        //需求:输入query pageNum pageSize 返回对应数据
        List<User> userList = userMapper.getByPage(pageResult);
        long total = userMapper.selectCount(null);
        return pageResult.setTotal(total).setRows(userList);
    }
    //*****************************************自己添加的部分******************************************************


//此后是老师接口方法

    /**
     * 获取user表
     * */
    @Override
    public List<User> findAll() {
        return userMapper.selectList(null);
    }

    /**
     * 业务需求：用户登录校验
     * 请求类型：post
     * url：/user/login
     * 参数：username/password
     * 返回值：SysResult对象 data的String类型的信息 token
     * <p>
     * 需求:
     * 1.根据用户名和密码查询数据库
     * 2.将密码进行加密处理 md5加密方式
     * 3.如果用户名和密码正确 返回token
     * 4 UUID: 每次生成的UUID几乎不重复.   重复概率 2^128/1
     * b809cd3e-f4fa-11eb-b396-52152e05da50
     *
     * @param user 作用: 在未来生成API文档时 有效果 一般都是默认的
     * @return
     */
    @Override
    public String login(User user) {
//        // 1.加密
//        String password=user.getPassword();
//        // 2.转化为字节数组
//        byte[] passByte = password.getBytes();
//        String md5Pass= DigestUtils.md5DigestAsHex(passByte);// Message-Digest Algorithm 5（信息-摘要算法5）
//        // 3.用用户名和密文查询
//        user.setPassword(md5Pass);
//断点按F6
        MyUtil.mySetMd5Password(user);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
        //获取结果
        User userDB = userMapper.selectOne(queryWrapper);
        //检查结果
        if (userDB == null) {//用户名和密码错误 返回null
            return null;
        }
        //正确 返回token
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 需求: 进行分页查询   总数 分页后的结果
     * 知识铺垫:  每页20条
     *      Sql: select * from user limit 起始位置,每页条数
     *      第一页:
     *          select * from user limit 0,20  下标[0-19]
     *      第二页:
     *          select * from user limit 20,20 下标[20-39]
     *      第三页:
     *          select * from user limit 40,20 下标[40-59]
     *      第N页:
     *          select * from user limit (n-1)*rows,rows
     * @param pageResult
     * @return
     *  方法实现:
     *          1.手写Sql
     *          2.利用MP方式实现
     *
     * 用户列表展现 老师的实现
     * 1.以MP的方式实现分页查询
     * 需求:
     * 1.分页查询List<User>
     * 2.获取记录总数
     *
     */
    @Override
    public PageResult getUserList(PageResult pageResult) {
        int pageNum = pageResult.getPageNum();//页面
        int pageSize = pageResult.getPageSize();//条数

        //参数1:page分页对象
        Page<User> page = new Page<User>(pageNum, pageSize);
        //参数2:查询条件
        //问题:如果用户没有传递query like关键字也会拼接参数
        //动态拼接:传参拼接like不传参就不拼接:condition: true拼接like条件
        //                                    false 不拼接like关键字
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        boolean queryFlag = StringUtils.hasLength(pageResult.getQuery());// 工具类 Spring提供
        queryWrapper.like(queryFlag, "username", pageResult.getQuery());// 查询条件
        //根据分页查询 返回 total/分页后的记录
        page = userMapper.selectPage(page, queryWrapper);// 返回IPage对象

        //第二部分!!!!!
        List<User> userList = page.getRecords();
        long total = page.getTotal();
        return pageResult.setTotal(total).setRows(userList);
    }
    /**
     * 用户列表展现 老师的实现
     * 2.在UserMapper接口中写sql语句实现
     * @param pageResult
     * @return
     * */
//    @Override
//    public PageResult getUserList(PageResult pageResult) {
//        //起始位置
//        int start = (pageResult.getPageNum() - 1) * pageResult.getPageSize();
//        //每页条数
//        int size = pageResult.getPageSize();
//        //分页结果
//        List<User> userList = userMapper.findUserListByPage(start, size);
//        //获取全部记录数 自动拆装箱 自动类型转换
//        long total = userMapper.selectCount(null);
//        //封装数据实现返回
//        return pageResult.setTotal(total).setRows(userList);
//    }

    /**
     * 根据id修改status
     */
    @Override
    public Integer updateStatus(User user) {
        //获取其他属性
        User user1 = userMapper.selectById(user);
        //获取当前时间
//        java.sql.Timestamp now = MyUtil.myTimeNow();
        //修改对象中status
        user1.setStatus(user.getStatus());
        //根据id修改
        return userMapper.updateById(user1);
    }

    /**
     * 增加数据
     *
     * */
    @Override
    public Integer insertUser(User user) {
        MyUtil.mySetMd5Password(user);
//        java.sql.Timestamp now = MyUtil.myTimeNow();
//        user.setCreated(now).setUpdated(now);
        return userMapper.insert(user);
    }

    /**
     * 根据id获取user
     * */
    @Override
    public User getUserById(Integer id) {
        return userMapper.selectById(id);
    }

    /**
     * 根据id删除user
     * 事务 全部成功或者全部失败
     *
     * 关于Spring中的事务策略说明
     *  0.Spring内部有事务的管理器,默认开启.
     *  1.Spring只负责拦截运行时异常.
     *    异常类型:  1.运行时异常  2.检查异常/编译异常 由程序员自己控制
     *  2.属性1: rollbackFor 可以配置特殊的异常类型.遇到某种异常回滚.
     *    属性2: noRollbackFor 可以配置异常类型 遇到某种异常不回滚.
     * @param id
     */
    @Override
    //异常控制
    @Transactional(rollbackFor = Exception.class)//遇见异常就回滚
    public Integer deleteUserById(Integer id) {
        return userMapper.deleteById(id);
    }

    /**
     * 根据id更新user
     * */
    @Override
    public Integer updateUserById(User user) {
        //获取其他属性
        User user1 = userMapper.selectById(user);
        //获取当前时间
//        java.sql.Timestamp now = MyUtil.myTimeNow();
        //赋值
        user1.setPhone(user.getPhone()).setEmail(user.getEmail());
        //根据id修改
        return userMapper.updateById(user1);
    }
}
